//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <elasys_server.h>
#include <sdl.h>
#include "keyboard_internal.h"
//
// The led control key hold
//
#define KBD_CAPSLOCK_HOLD       0x04
#define KBD_NUMLOCK_HOLD        0x02
#define KBD_SCROLLLOCK_HOLD     0x01

//
// CTRL, ALT, SHIFT status
//
#define KBD_CTRL                0x0001
#define KBD_ALT                 0x0002
#define KBD_SHIFT               0x0004

Byte  g_byS2VTable[323] = {
    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x8,  0x9,
    0x0,  0x0,  0xc,  0xd,  0x0,  0x0,  0x0,  0x0,  0x0,  0x13,
    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x1b, 0x0,  0x0,
    0x0,  0x0,  0x20, 0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0xDE,
    0x0,  0x0,  0x0,  0x0,  0xBC, 0xBD, 0xBE, 0xBF, 0x30, 0x31,
    0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x0,  0xBA,
    0x0,  0xBB, 0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,
    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,
    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,
    0x0,  0xDB, 0xDC, 0xDD, 0x0,  0x0,  0xC0, 0x41, 0x42, 0x43, //99
    0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d,
    0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
    0x58, 0x59, 0x5a, 0x0,  0x0,  0x0,  0x0,  0x2E, 0x0,  0x0,
    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,
    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,
    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,
    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,
    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,
    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,
    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0, //199
    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,
    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,
    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,
    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,
    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x0,
    0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x60, 0x61, 0x62, 0x63,
    0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6E, 0x6F, 0x6A, 0x6D,
    0x6B, 0x6c, 0x0,  0x26, 0x28, 0x27, 0x25, 0x2D, 0x24, 0x23,
    0x21, 0x22, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
    0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x0,  0x0,  0x0, //299
    0x90, 0x14, 0x91, 0xA1, 0xA0, 0xA3, 0xA2, 0xA5, 0xA4, 0x0,
    0x0,  0x5B, 0x5C, 0x0,  0x0,  0x2F, 0x2C, 0x0,  0x0,  0x0,
    0x0,  0x0,  0x0
};

static UInt32 _Keyboard_GetState(UInt32 iState)
{
     UInt32 iRet = 0, iLockRet = 0, iModRet = 0;
    //numlock, capslock(scrollock is not support in SDL)
    if (iState & KMOD_NUM) {
        iLockRet |= KBD_NUMLOCK_HOLD;
    }
    else {
        iLockRet &= ~KBD_NUMLOCK_HOLD;
    }
    if (iState & KMOD_CAPS) {
        iLockRet |= KBD_CAPSLOCK_HOLD;
    }
    else {
        iLockRet &= ~KBD_CAPSLOCK_HOLD;
    }

    //shift, ctrl, alt
    if (iState & KMOD_CTRL) {
        iModRet |= KBD_CTRL;
    }
    else {
        iModRet &= ~KBD_CTRL;
    }
    if (iState & KMOD_SHIFT) {
        iModRet |= KBD_SHIFT;
    }
    else {
        iModRet &= ~KBD_SHIFT;
    }
    if (iState & KMOD_ALT) {
        iModRet |= KBD_ALT;
    }
    else {
        iModRet &= ~KBD_ALT;
    }
    iRet = iLockRet | (iModRet << 16);
    return iRet;
}

void Keyboard_PressKey(SDL_Event * pSDLEvent, KPD_DATA * pKpdData)
{
    switch(pSDLEvent->type) {
    case SDL_KEYDOWN:{
        pKpdData->keycode = g_byS2VTable[pSDLEvent->key.keysym.sym];
        pKpdData->status = KEYDOWN;
        UInt32 iRet = _Keyboard_GetState(pSDLEvent->key.keysym.mod);
        UInt8 uLedStatus = iRet & 0xff;
        UInt8 uKbdStatus = (iRet >> 16) & 0xff;
        pKpdData->status |= ((UInt32)uLedStatus << 16) + (uKbdStatus<<1);
        //assert(0==(pKpdData->status&0x1));
        break;
    }

    case SDL_KEYUP:
        pKpdData->keycode = g_byS2VTable[pSDLEvent->key.keysym.sym];
        pKpdData->status  = KEYUP;
        break;
    default:
        assert(0);
        break;
    }
}

